package com.example.demo.expansion

import io.vertx.core.eventbus.EventBus
import io.vertx.core.eventbus.Message
import io.vertx.ext.web.Route
import io.vertx.ext.web.RoutingContext
import io.vertx.kotlin.coroutines.awaitResult
import io.vertx.sqlclient.Pool
import io.vertx.sqlclient.SqlConnection
import io.vertx.sqlclient.Transaction
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.slf4j.LoggerFactory

private val logger = LoggerFactory.getLogger("expansion")

fun Route.coroutineHandler(fn: suspend (RoutingContext) -> Unit) {
  this.handler { ctx ->
    GlobalScope.launch {
      try {
        fn(ctx)
      } catch (e: Exception) {
        ctx.fail(e)
      }
    }
  }
}

// 扩展方法：自动管理事务
suspend fun Pool.withTx(f: suspend (SqlConnection) -> Unit, ex: (Exception) -> Unit) {
  val conn: SqlConnection
  try {
    conn = awaitResult { this.getConnection(it) }
  } catch (e: Exception) {
    logger.error("获取数据库连接失败：${e.message}", e)
    return
  }
  var tx: Transaction? = null
  try {
    tx = awaitResult { conn.begin(it) }
    f(conn)
    awaitResult<Void> { tx?.commit() }
    logger.info("事务提交")
  } catch (e: Exception) {
    logger.error("业务处理失败：${e.message}", e)
    awaitResult<Void> { tx?.rollback(it) }
    logger.info("事务回滚完成")
    ex(e)
  } finally {
    conn.close()
  }
}

suspend fun Pool.conn(f: suspend (SqlConnection) -> Unit, ex: (Exception) -> Unit) {
  val conn: SqlConnection
  try {
    conn = awaitResult { this.getConnection(it) }
  } catch (e: Exception) {
    logger.error("获取数据库连接失败：${e.message}", e)
    return
  }
  try {
    f(conn)
  } catch (e: Exception) {
    logger.error("业务处理失败：${e.message}", e)
    ex(e)
  } finally {
    conn.close()
  }
}

// 扩展方法：等待 EventBus 上的事件
suspend fun <T> EventBus.awaitLocalConsumer(address: String, handler: suspend (Message<T>) -> Unit) {
  this.localConsumer<T>(address) {
    logger.info("eventBus 地址：${address} 收到消息")
    GlobalScope.launch {
      handler(it)
    }
  }
}
